package juego;
/**
 * Clase que representa el hilo en el que se ejecuta el juego.
 * @author Miguel Vicente
 */
public abstract class HiloJuego extends Thread {
	
	private boolean terminado;
	private boolean pausado;
	private int maxFPS;
	private int maxFramesSaltados;
	private double delta;
	/**
	 * Constructor.<br>
	 * Los parametros por defecto son: maxFPS=60 y maxFramesSaltados=5
	 */
	public HiloJuego() {
		this.terminado = false;
		this.pausado = false;
		this.maxFPS = 60;
		this.maxFramesSaltados = 5;
		this.delta = 1000 / maxFPS;
	}
	/**
	 * Constructor.<br>
	 * Por defecto maxFramesSaltados=5
	 * @param maxFPS Maximo numero de FPS al que se permitira actualizar el juego.
	 */
	public HiloJuego(int maxFPS) {
		this.terminado = false;
		this.pausado = false;
		this.maxFPS = maxFPS;
		this.maxFramesSaltados = 5;
		this.delta = 1000 / maxFPS;
	}
	/**
	 * Constructor.<br>
	 * @param maxFPS Maximo numero de FPS al que se permitira actualizar el juego.
	 * @param maxFramesSaltados Maximo numero de frames seguidos en los que se actualiza la logica
	 * del juego sin renderizar en caso de que el renderizado consuma demasiado tiempo.
	 */
	public HiloJuego(int maxFPS, int maxFramesSaltados) {
		this.terminado = false;
		this.pausado = false;
		this.maxFPS = maxFPS;
		this.maxFramesSaltados = maxFramesSaltados;
		this.delta = 1000 / maxFPS;
	}

	@Override
	public void run() {
		long tInicio;
		long tCiclo;
		int framesSaltados;
		int tEspera = 0;

		while (!terminado) {
			tInicio = System.currentTimeMillis();
			framesSaltados = 0;
			if (!pausado) {
				actualizar(delta*0.001);
			}
			renderizar();
			tCiclo = System.currentTimeMillis() - tInicio;
			tEspera = (int)(delta - tCiclo);
			if (tEspera > 0) {
				try {
					Thread.sleep(tEspera);
				} catch (InterruptedException e) {}
			}
			// Actualizamos sin renderizar
			while ((tEspera < 0) && (framesSaltados < maxFramesSaltados) && (!pausado)) {
				actualizar(delta*0.001);
				tEspera += delta;
				framesSaltados++;
			}
		}
	}
	/**
	 * Actualiza la logica del juego.
	 * @param delta Tiempo
	 */
	public abstract void actualizar(double delta);
	/**
	 * Renderiza los componentes graficos del juego.
	 */
	public abstract void renderizar();
	/**
	 * Pausa la actualizacion de la logica del juego.
	 */
	public void pausar() {
		pausado = true;
	}
	/**
	 * Reanuda la actualizacion de la logica del juego.
	 */
	public void reanudar() {
		pausado = true;
	}
	/**
	 * Termina el juego.
	 */
	public void terminar() {
		terminado = true;
	}
	
}
